<template>
  <n-card>
    <template #header>
      <div class="title-bar">
        <n-menu v-model:value="activeKey" mode="horizontal" :options="menuOptions" />
        <div class="tool">
          <n-button text class="minimize" @click="minimize">
            <template #icon>
              <n-icon>
                <Minus />
              </n-icon>
            </template>
          </n-button>
          <n-button text class="close" @click="close">
            <template #icon>
              <n-icon>
                <Close />
              </n-icon>
            </template>
          </n-button>
        </div>
      </div>
    </template>
    <n-page-header subtitle="更懂你的截图录屏软件">
      <n-grid :cols="5" :x-gap="5">
        <n-gi>
          <div class="main-function-item">
            <div class="label">声音</div>
            <n-space justify="center">
              <div class="btn" :class="audioInputDevice && audioInputDevice.length <= 0 ? 'btn disabled' : 'btn'">
                <i class="iconfont icon-sound" />
              </div>
              <n-slider v-model:value="audioVolume" vertical :step="1">
                <template #thumb>
                  <n-icon-wrapper :size="10" :border-radius="10">
                    <n-icon :size="10">
                      <circle />
                    </n-icon>
                  </n-icon-wrapper>
                </template>
              </n-slider>
            </n-space>
            <div class="tips">
              <n-select v-model="currentAudioInputDevice" label-field="label" value-field="deviceId" title="label" size="tiny" :options="audioInputDevice" placeholder="默认扬声器" :disabled="audioInputDevice && audioInputDevice.length <= 0" />
            </div>
          </div>
        </n-gi>
        <n-gi>
          <div class="main-function-item">
            <div class="label">麦克风</div>
            <n-space justify="center">
              <div class="btn" :class="audioInputDevice && audioInputDevice.length <= 0 ? 'btn disabled' : 'btn'">
                <i class="iconfont icon-microphone" />
              </div>
              <n-slider v-model:value="microVolume" vertical :step="1">
                <template #thumb>
                  <n-icon-wrapper :size="10" :border-radius="10">
                    <n-icon :size="10">
                      <circle />
                    </n-icon>
                  </n-icon-wrapper>
                </template>
              </n-slider>
            </n-space>
            <div class="tips">
              <n-select v-model="currentAudioInputDevice" label-field="label" value-field="deviceId" title="label" size="tiny" :options="audioInputDevice" placeholder="默认麦克风" :disabled="audioInputDevice && audioInputDevice.length <= 0" />
            </div>
          </div>
        </n-gi>
        <n-gi>
          <div class="main-function-item">
            <div class="label">摄像头</div>
            <div :class="videoInputDevice && videoInputDevice.length <= 0 ? 'btn disabled' : 'btn'">
              <i class="iconfont icon-camera" />
            </div>
            <div class="tips">
              <n-select v-model="currentVideoInputDevice" label-field="label" value-field="deviceId" title="label" size="tiny" :options="videoInputDevice" placeholder="默认摄像头" :disabled="videoInputDevice && videoInputDevice.length <= 0" />
            </div>
          </div>
        </n-gi>
<!--        <n-gi>-->
<!--          <div class="main-function-item">-->
<!--            <div class="label">区域</div>-->
<!--            <div class="btn" @click="selectRegion">-->
<!--              <i class="iconfont icon-region" />-->
<!--            </div>-->
<!--            <div class="tips">{{bounds.width}} * {{bounds.height}}</div>-->
<!--          </div>-->
<!--        </n-gi>-->
        <n-gi>
          <div class="main-function-item">
            <div class="label">截图</div>
            <div class="btn" @click="screenshot">
              <i class="iconfont icon-screenshot" />
            </div>
            <div class="tips">开始截图</div>
          </div>
        </n-gi>
        <n-gi>
          <div class="main-function-item">
            <div class="label">录屏</div>
            <template v-if="!isStarted">
              <div class="btn" @click="startRecord">
                <i class="iconfont icon-record" />
              </div>
              <div class="tips">开始录制屏幕</div>
            </template>
            <template v-else>
              <div class="btn" @click="stopRecord">
                <i class="iconfont icon-stop" />
              </div>
              <div class="tips">{{computedDuration}}</div>
            </template>
          </div>
        </n-gi>
      </n-grid>
      <template #title>
        <div class="official-website" @click="openOfficialWebsite">Dreamer Screen（{{version}}）</div>
      </template>
      <template #avatar>
        <n-avatar :src="logo" circle />
      </template>
      <template #extra>
        <n-space>
          <n-button>催更</n-button>
          <n-dropdown :options="options" placement="bottom-start">
            <n-button :bordered="false" style="padding: 0 4px">
              ···
            </n-button>
          </n-dropdown>
        </n-space>
      </template>
    </n-page-header>
  </n-card>
</template>

<script lang="ts">
import { NIcon, createDiscreteApi } from 'naive-ui'
import {defineComponent, h, ref, Component, toRaw} from 'vue'
import packageJSON from '@package.json'
import { number2date } from '@renderer/utils'
import {
  Circle,
  Menu2 as Menu,
  Tool as Tool,
  User as User,
  Minus as Minus,
  X as Close
} from '@vicons/tabler'

const { dialog } = createDiscreteApi(['dialog'])

export default defineComponent({
  name: 'Main',
  components: {
    Circle, Minus, Close
  },
  setup () {
    return {
      logo: new URL('@renderer/assets/1.png', import.meta.url).href,
      officialWebsite: 'http://screen.iteachyou.cc',
      version: packageJSON.version,
      activeKey: '',
      menuOptions: [
        {
          label: '文件',
          key: 'file',
          icon: loadIcon(Menu),
          children: [
            {
              label: '工作目录',
              key: 'workspace'
            },
            {
              label: () => h(
                  "div",
                  {
                    onClick: () => {
                      alert(1)
                    },
                  },
                  "退出"
              ),

              key: 'exit'
            }
          ]
        },
        {
          label: '工具',
          key: 'tool',
          icon: loadIcon(Tool),
          children: [
            {
              label: '首选项',
              key: 'preferences'
            }
          ]
        },
        {
          label: '关于',
          key: 'about',
          icon: loadIcon(User),
          children: [
            {
              label: '检查更新',
              key: 'check-updator'
            },
            {
              label: '意见反馈',
              key: 'feedback'
            },
            {
              label: '版权所有',
              key: 'copyright'
            },
            {
              label: '关于软件',
              key: 'about-software'
            }
          ]
        }
      ],
      audioInputDevice: ref([]),
      currentAudioInputDevice: ref({}),
      audioVolume: ref(80),
      videoInputDevice: ref([]),
      currentVideoInputDevice: ref({}),
      microVolume: ref(80),
      bounds: ref({
        x: 0,
        y: 0,
        width: 1920,
        height: 1080
      }),
      isStarted: ref(false),
      duration: ref(0),
      intervalId: ref(''),
      recorder: null,
      saveDir: '',
    }
  },
  computed: {
    computedDuration(){
      return number2date(this.duration)
    }
  },
  beforeMount() {
    window.electron.ipcRenderer.on('main-to-renderer', (e, data) => {
      const event = data.data
      if(data.name === 'did-region-finished'){
        this.bounds = event
      }
    })

    // 检测设备
    navigator.mediaDevices.enumerateDevices().then((devices) => {
      devices.forEach((device) => {
        // 音频设备
        if (device.kind == 'audioinput') {
          this.audioInputDevice.push(device)
        }else if (device.kind == 'videoinput') { // 视频设备
          this.videoInputDevice.push(device)
        }
      })
      // 默认音频输入设备
      this.currentAudioInputDevice = this.audioInputDevice && this.audioInputDevice.length > 0 ? this.audioInputDevice[0].deviceId : null
      // 默认视频输入设备
      this.currentVideoInputDevice = this.videoInputDevice && this.videoInputDevice.length > 0 ? this.videoInputDevice[0].deviceId : null
    }).catch((err) => {
      console.error(`错误发生 ${err.name}: ${err.message}`);
    });
  },
  methods: {
    openOfficialWebsite(){
      window.electron.ipcRenderer.invoke("renderer-to-main", {
        name: 'open-external-url',
        event: 'event',
        data: this.officialWebsite
      })
    },
    selectRegion(){
      window.electron.ipcRenderer.invoke("renderer-to-main", {
        name: 'select-region',
        event: 'event',
        data: null
      })
    },
    screenshot(){
      window.electron.ipcRenderer.invoke("renderer-to-main", {
        name: 'open-screenshot',
        event: 'event',
        data: null
      })
    },
    startRecord(){
      this.intervalId = setInterval(() => {
        this.duration += 1
      }, 1000)
      window.electron.ipcRenderer.on('main-to-renderer', async (event, data) => {
        if(data.name === 'start-recording'){
          try {
            const sourceId = data.data.sourceID
            this.saveDir = data.data.saveDir
            const stream = await navigator.mediaDevices.getUserMedia({
              audio: true,
              video: {
                mandatory: {
                  chromeMediaSource: 'desktop',
                  chromeMediaSourceId: sourceId,
                  minWidth: 1280,
                  maxWidth: 1280,
                  minHeight: 720,
                  maxHeight: 720
                }
              }
            })
            console.log(stream, 1)
            this.handleStream(stream)
          } catch (e) {
            console.log(e)
          }
        }
      })
      const rectangle = toRaw(this.bounds)
      const data = {
        rectangle,
        region: 'window'
      }
      window.electron.ipcRenderer.invoke("renderer-to-main", {
        name: 'start-record',
        event: 'event',
        data: data
      })
      this.isStarted = true
    },
    stopRecord(){
      clearInterval(this.intervalId)
      if(this.recorder != null){
        this.recorder.stop()
      }
      window.electron.ipcRenderer.invoke("renderer-to-main", {
        name: 'stop-record',
        event: 'event',
        data: null
      })
      this.recorder = null
      this.isStarted = false
    },
    minimize(){
      window.electron.ipcRenderer.invoke("renderer-to-main", {
        name: 'app-minimize',
        event: 'event',
        data: null
      })
    },
    close(){
      dialog.error({
        maskClosable: false,
        title: '系统提示',
        content: '您确定要退出Dreamer Screen吗？',
        negativeText: '取消',
        positiveText: '确定',
        onPositiveClick: () => {
          window.electron.ipcRenderer.invoke("renderer-to-main", {
            name: 'app-quit',
            event: 'event',
            data: null
          })
        },
        onNegativeClick: () => {
          dialog.destroyAll()
        }
      })
    },
    handleStream(stream) {
      this.recorder = new MediaRecorder(stream);
      this.recorder.start();
      // 如果 start 没设置 timeslice，ondataavailable 在 stop 时会触发
      this.recorder.ondataavailable = event => {
        console.log(event);
        let blob = new Blob([event.data], {
          type: 'video/mp4',
        });
        this.saveMedia(blob);
      };
      this.recorder.onerror = err => {
        console.error(err);
      };
    },
    saveMedia(blob) {
      let reader = new FileReader();
      reader.onload = () => {
        let buffer = new window.api.Buffer(reader.result);
        const filename = new Date().getTime();
        console.log(this.saveDir + 'DS录屏_' + filename + '.mp4')
        window.api.fs.writeFile(this.saveDir + '/' + 'DS录屏_' + filename + '.mp4', buffer, {}, (err, res) => {
          if (err) return console.error(err);
        });
      };
      reader.onerror = err => console.error(err);
      reader.readAsArrayBuffer(blob);
    }
  }
})

const loadIcon = (icon: Component) => {
  return () => h(NIcon, null, { default: () => h(icon) })
}

</script>

<style lang="less" scoped>
:deep(.n-card-header){
  user-select: none;
  -webkit-app-region: drag;
}
:deep(.n-card-header .n-menu){
  user-select: none;
  -webkit-app-region: no-drag;
}
:deep(.n-menu-item-content){
  padding-left: 0 !important;
}
.title-bar{
  display: flex;
  justify-content: space-between;
  .tool{
    user-select: none;
    -webkit-app-region: no-drag;
    display: flex;
    .minimize, .close {
      margin-left: 15px;
      cursor: pointer;
    }
  }
}
.official-website{
  cursor: pointer;
}
.main-function-item {
  padding: 10px;
  cursor: pointer;
  border-radius: 10px;
  background-color: rgba(20, 80, 20, 0.2);
  height: 120px;
  .label {
    color: rgba(255, 255, 255, 0.52);
  }

  .btn {
    width: 50px;
    height: 50px;
    margin: 5px auto 5px auto;
    line-height: 50px;
    text-align: center;
    border-radius: 50%;
    border: rgba(255, 255, 255, .1) solid 5px;
    .iconfont {
      font-size: 35px;
    }
    .icon-stop{
      color: #cc3344 !important;
    }
  }

  .btn:hover {
    background-color: rgba(255, 255, 255, .12);
    .iconfont {
      color: #cc3344;
    }
  }

  .disabled:hover{
    cursor: not-allowed;
    background-color: unset !important;
    .iconfont {
      color: unset !important;
    }
  }

  .tips{
    color: #aaaaaa;
    text-align: center;
    height: 30px;
    line-height: 30px;
    font-size: 12px;
  }
}
</style>
